package com.fbinggun.fattribute.data;

import com.fbinggun.fattribute.FAttributePlugin;
import com.fbinggun.fattribute.attribute.IAttribute;
import com.fbinggun.fattribute.attribute.other.AttackSpeed;
import com.fbinggun.fattribute.attribute.other.Health;
import com.fbinggun.fattribute.effect.IEffect;
import com.fbinggun.fattribute.status.Modifier;
import com.fbinggun.fattribute.status.StatusMap;
import com.fbinggun.fattribute.util.AttributUtil;
import org.bukkit.entity.LivingEntity;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;

import java.util.*;

public class EntityData {
    LivingEntity entity;
    public StatusMap statusMap;
    UUID uuid;
    public Map<IEffect,Integer> iEffects = new HashMap<>();
    public static List<IUpDate> upDates =new ArrayList<>();


    public static void registerUpData(IUpDate upDate){
        upDates.add(upDate);
    }

    public void addEffect(IEffect effect){
        iEffects.put(effect,effect.getDuration());
    }

    public void tick(){
        if(entity==null){
            return;
        }
        if(iEffects.size()!=0){
            List<IEffect> delEffect = new ArrayList<>();
            for(IEffect effect:iEffects.keySet()){
                int duration= iEffects.get(effect);
                duration--;
                iEffects.put(effect,duration);
                effect.tick(this);
                if(duration==0){
                    delEffect.add(effect);
                }

            }
            if(delEffect.size()!=0){
                for(IEffect effect:delEffect) {
                    iEffects.remove(effect);
                }
            }
        }
    }

    public Map<IEffect, Integer> getiEffects() {
        return iEffects;
    }

    public LivingEntity getEntity() {
        return entity;
    }

    public EntityData(LivingEntity entity) {
        this.entity=entity;
        this.statusMap = new StatusMap();
        uuid=entity.getUniqueId();
         getEquipmentSlot();
        new BukkitRunnable() {
            @Override
            public void run() {
                if(entity==null){
                    DataManage.delData(entity.getUniqueId());
                    cancel();
                    return;
                }
                if(entity.isDead()){
                    DataManage.delData(entity.getUniqueId());
                    cancel();
                    return;
                }
                up();
            }
        }.runTaskTimerAsynchronously(FAttributePlugin.plugin,30,30);
    }

    public void up(){
        if(upDates!=null&&upDates.size()!=0){
            for(IUpDate upDate:upDates){
                upDate.up(this);
            }
        }
        getEquipmentSlot();

        if(statusMap.getAttributeMap()!=null&&statusMap.getAttributeMap().size()!=0) {
            for (IAttribute attribute : statusMap.getAttributeMap().keySet()) {
                attribute.up(this);
            }
        }
        double attackSpeed = this.getValue(FAttributePlugin.plugin.getConfigKey("AttackSpeed"));
        double health = this.getValue(FAttributePlugin.plugin.getConfigKey("Health"));

        if(health==0){
            Health.remove(this);
        }
        if(attackSpeed==0){
            AttackSpeed.remove(this);
        }
    }
    protected Map<IAttribute,Double> getEquipmentSlot(){
        Map<IAttribute,Double> map = new HashMap<>();
        if(entity.getEquipment()!=null) {
            for (ItemStack itemStack : entity.getEquipment().getArmorContents()) {
                if(entity.getEquipment().getItemInOffHand().isSimilar(itemStack)){
                    continue;
                }
                if(entity.getEquipment().getItemInMainHand().isSimilar(itemStack)){
                    continue;
                }
                Map<IAttribute, Double> loreAttribute = AttributUtil.getAttribut(itemStack);
                if (loreAttribute != null && loreAttribute.size() != 0) {
                    map = addAttributeValue(map, loreAttribute);
                }
            }
            ItemStack hand = entity.getEquipment().getItemInMainHand();
            Map<IAttribute, Double> handAttribute = AttributUtil.getAttribut(hand);
            if (handAttribute != null && handAttribute.size() != 0) {
                map = addAttributeValue(map, handAttribute);
            }
//            ItemStack offHand = entity.getEquipment().getItemInOffHand();
//            Map<IAttribute, Double> offHandAttribute = AttributUtil.getAttribut(offHand);
//            if (offHandAttribute != null && offHandAttribute.size() != 0) {
//                map = addAttributeValue(map, offHandAttribute);
//            }
            if (map != null && map.size() != 0) {
                statusMap.addModifier(new Modifier("FAttributePlugin_EquipmentSlot", FAttributePlugin.plugin, map));
            } else {
                statusMap.removeModifier("FAttributePlugin_EquipmentSlot");
            }
        }
        return map;
    }



    public double getValue(String key){
        return statusMap.getVlues(key);
    }
    public IAttribute getAttribute(String key){
        return IAttribute.getKey(key);
    }

    public UUID getUuid() {
        return uuid;
    }

    public StatusMap getStatusMap() {
        return statusMap;
    }

 public void addModifier(Modifier modifier){
        getStatusMap().addModifier(modifier);
 }
    private Map<IAttribute,Double> addAttributeValue(Map<IAttribute,Double> map, Map<IAttribute,Double> map2){
        for(IAttribute iAttribute:map.keySet()){
            double value =map.get(iAttribute);
            if(map2.get(iAttribute)!=null){
                value=map2.get(iAttribute)+value;
            }
            map.put(iAttribute,value);
            map2.remove(iAttribute);
        }
        if(map2.size()!=0) {
            map.putAll(map2);
        }
        return map;
    }
}
